﻿#include "PolarTracer.h"
#include "PolarGraph.h"
#include "PostEnumType.h"
#include "DataManager/WindowTotalData.h"

namespace pst
{

    PolarTracerTableWidget::PolarTracerTableWidget(QCustomPlot* parent)
        : TracerTableWidget(parent)
    {
        this->setHorizontalHeaderItem(0, new QTableWidgetItem("标记名"));
        this->setHorizontalHeaderItem(1, new QTableWidgetItem("角度值"));
        this->setHorizontalHeaderItem(2, new QTableWidgetItem("数值"));
    }

    void PolarTracerTableWidget::AppendTracerProperty(LineChartTracer* tracer)
    {
        this->insertRow(this->rowCount());
        auto nameItem = new QTableWidgetItem(tracer->GetName());
        nameItem->setData(QVariant::UserType, QVariant::fromValue(tracer));
        this->setItem(this->rowCount() - 1, 0, nameItem);

        auto angleItem = new QTableWidgetItem(QString::number(tracer->getPolarGraphAngleCoord()));
        angleItem->setData(QVariant::UserType, QVariant::fromValue(tracer));
        this->setItem(this->rowCount() - 1, 1, angleItem);

        auto radiusItem = new QTableWidgetItem(QString::number(tracer->getPolarGraphRadiusCoord()));
        radiusItem->setData(QVariant::UserType, QVariant::fromValue(tracer));
        this->setItem(this->rowCount() - 1, 2, radiusItem);

        auto valueItem = new QTableWidgetItem(QString::number(tracer->GetValue()));
        valueItem->setData(QVariant::UserType, QVariant::fromValue(tracer));
        this->setItem(this->rowCount() - 1, 3, valueItem);
    }

    QDomElement& PolarTracerTableWidget::writeToProjectFile(QDomDocument* doc, QDomElement* element, GraphType graphType, bool isdiso)
    {
        QDomElement _TracerTableWidgetDataRoot = doc->createElement("PolarTracerTableWidget");
        QDomAttr idattr = doc->createAttribute("ID");
        idattr.setValue(QString::number(1));
        _TracerTableWidgetDataRoot.setAttributeNode(idattr);

        for (int i = 0; i < this->rowCount(); ++i)
        {
            auto tracer = this->item(i, 0)->data(QVariant::UserType).value<LineChartTracer*>();
            tracer->writeToProjectFile(doc, &_TracerTableWidgetDataRoot, GraphType::PolarGraph, isdiso);
        }

        element->appendChild(_TracerTableWidgetDataRoot);

        return _TracerTableWidgetDataRoot;
    }

    void PolarTracerTableWidget::readFromProjectFile(QDomNodeList* nodelist, QCustomPlot* customPlot, GraphType graphType, bool isdiso)
    {
        auto _element = nodelist->at(0).toElement();
        auto _nodelist = _element.elementsByTagName("LineChartTracer");
        auto _tracerCount = _nodelist.count();
        for (int i = 0; i < _tracerCount; ++i)
        {
            auto _tracerElement = _nodelist.at(i).toElement();
            auto tracer = new LineChartTracer(customPlot);
            tracer->readFromProjectFile(&_tracerElement, GraphType::PolarGraph, isdiso);

            auto _info = WindowTotalDataInstance->getInfomationCurve2DBasicalByID(tracer->getCurveInfoID());
            PolarGraph* graph = qobject_cast<PolarGraph*>(_info->getCurveLineAddress());
            graph->addTracer(tracer);
            tracer->position->setType(QCPItemPosition::PositionType::ptAbsolute);
            tracer->updatePositionOnPolar();

            this->AppendTracerProperty(tracer);
            auto tmpProperty = tracer->getStyle2DTracerProperty();
            if (tmpProperty == nullptr)
                return;
            tracer->SetName(tmpProperty->m_tracerName);
            tracer->setGraphKey(tmpProperty->m_x);
            tracer->setStyle(QCPItemTracer::TracerStyle(tmpProperty->m_symbolStyle + 1));
            tracer->setSize(tmpProperty->m_symbolSize * 2);
            tracer->setPen(QPen(tmpProperty->m_symbolColor));
        }
    }

    void PolarTracerTableWidget::slot_updateTracerProperty()
    {
        //if (this->isHidden())
        //{
        //    return;
        //}
        bool hasVisibleRow = false;
        for (int i = 0; i < this->rowCount(); ++i)
        {
            auto tracer = this->item(i, 0)->data(QVariant::UserType).value<LineChartTracer*>();
            if (tracer->visible())
            {
                this->item(i, 0)->setText(tracer->GetName());
                this->item(i, 1)->setText(QString::number(tracer->getPolarGraphAngleCoord()));
                this->item(i, 2)->setText(QString::number(tracer->getPolarGraphRadiusCoord()));
                this->item(i, 3)->setText(QString::number(tracer->GetValue()));
                this->showRow(i);
                hasVisibleRow = true;

                auto property = tracer->getStyle2DTracerProperty();
                property->m_x = tracer->getPolarGraphAngleCoord();
                property->m_y = tracer->getPolarGraphRadiusCoord();
            }
            else
            {
                this->hideRow(i);
            }
        }
        hasVisibleRow ? this->show() : this->hide();
    }

    void PolarTracerTableWidget::slot_updateTracerChange()
    {
        TracerTableWidget::slot_updateTracerChange();
    }

    // ------------------------------------------------------------------

    PolarMeasureTableWidget::PolarMeasureTableWidget(QCustomPlot* parent)
        : MeasureTableWidget(parent)
    {
    }

    void PolarMeasureTableWidget::AppendTracerProperty(LineChartTracer* tracer)
    {
        this->insertRow(this->rowCount());
        auto graphNameItem = new QTableWidgetItem(qobject_cast<QCPPolarGraph*>(tracer->GetLayerable())->name());
        graphNameItem->setData(QVariant::UserType, QVariant::fromValue(tracer));
        this->setItem(this->rowCount() - 1, 0, graphNameItem);

        auto nameItem = new QTableWidgetItem(tracer->GetName());
        nameItem->setData(QVariant::UserType, QVariant::fromValue(tracer));
        this->setItem(this->rowCount() - 1, 1, nameItem);

        if (tracer->GetName() == getMeasureTypeName(MeasureType::HalfPowerBeamWidth))
        {
            auto indeicator = qobject_cast<BeamBandwidthTracer*>(tracer)->GetIndicator();
            double difference = std::abs(indeicator->start->coords().x() - indeicator->end->coords().x());
            auto differenceItem = new QTableWidgetItem(QString::number(difference));
            differenceItem->setData(QVariant::UserType, QVariant::fromValue(tracer));
            this->setItem(this->rowCount() - 1, 2, differenceItem);
        }
        else
        {
            auto yItem = new QTableWidgetItem(QString::number(tracer->position->coords().y()));
            yItem->setData(QVariant::UserType, QVariant::fromValue(tracer));
            this->setItem(this->rowCount() - 1, 2, yItem);
        }

        //半功率带宽 先不显示
        BeamBandwidthTracer* halfPowerTracer = qobject_cast<BeamBandwidthTracer*>(tracer);
        if (halfPowerTracer != nullptr)
        {
            this->hideRow(this->rowCount() - 1);
        }
    }

    QDomElement& PolarMeasureTableWidget::writeToProjectFile(QDomDocument* doc, QDomElement* element, bool isdiso)
    {
        QDomElement _MeasureTableWidgetDataRoot = doc->createElement("PolarMeasureTableWidget");
        QDomAttr idattr = doc->createAttribute("ID");
        idattr.setValue(QString::number(1));
        _MeasureTableWidgetDataRoot.setAttributeNode(idattr);

        for (int i = 0; i < this->rowCount(); ++i)
        {
            auto tracer = this->item(i, 0)->data(QVariant::UserType).value<LineChartTracer*>();
            tracer->writeToProjectFile(doc, &_MeasureTableWidgetDataRoot, GraphType::PolarGraph, isdiso);
        }

        element->appendChild(_MeasureTableWidgetDataRoot);

        return _MeasureTableWidgetDataRoot;
    }

    void PolarMeasureTableWidget::readFromProjectFile(QDomNodeList* nodelist, QCustomPlot* customPlot, bool isdiso)
    {
        auto _element = nodelist->at(0).toElement();
        auto _nodelist = _element.elementsByTagName("LineChartTracer");
        auto _tracerCount = _nodelist.count();
        for (int i = 0; i < _tracerCount; ++i)
        {
            auto _tracerElement = _nodelist.at(i).toElement();
            auto _TracerType = _tracerElement.attribute("TracerType");
            LineChartTracer* tracer = nullptr;
            if (_TracerType == "BeamBandwidth")
            {
                auto _temptracer = new BeamBandwidthTracer(customPlot);
                _temptracer->readFromProjectFile(&_tracerElement, GraphType::PolarGraph, isdiso);
                QCPItemLine* indicator = _temptracer->GetIndicator();
                indicator->start->setType(QCPItemPosition::PositionType::ptAbsolute);
                indicator->end->setType(QCPItemPosition::PositionType::ptAbsolute);
                tracer = _temptracer;
            }
            else
            {
                tracer = new LineChartTracer(customPlot);
                tracer->readFromProjectFile(&_tracerElement, GraphType::PolarGraph, isdiso);
            }
            tracer->position->setType(QCPItemPosition::PositionType::ptAbsolute);
            auto _info = WindowTotalDataInstance->getInfomationCurve2DBasicalByID(tracer->getCurveInfoID());
            PolarGraph* polarGraph = qobject_cast<PolarGraph*>(_info->getCurveLineAddress());
            polarGraph->addTracer(tracer);

            this->AppendTracerProperty(tracer);
        }
    }

    void PolarMeasureTableWidget::slot_updateTracerProperty()
    {
        //if (this->isHidden())
        //{
        //    return;
        //}

        bool hasVisibleRow = false;
        for (int i = 0; i < this->rowCount(); ++i)
        {
            auto tracer = this->item(i, 0)->data(QVariant::UserType).value<LineChartTracer*>();
            PolarGraph* graph = qobject_cast<PolarGraph*>(tracer->getPolarGraph());
            if (graph == nullptr)
            {
                continue;
            }
            const auto& graphData = graph->data();
            bool findRange = false;
            auto range = graphData->valueRange(findRange);
            double key = 0;
            double value = 0;
            if (!findRange)
            {
                tracer->setVisible(false);
                this->hideRow(i);
                continue;
            }
            if (tracer->GetName() == getMeasureTypeName(MeasureType::HalfPowerBeamWidth))
            {
                // tracer->setVisible(graph->visible());
                if (!tracer->visible())
                {
                    this->hideRow(i);
                    continue;
                }
                auto indeicator = qobject_cast<BeamBandwidthTracer*>(tracer)->GetIndicator();
                double startAngle = 0.0;
                double startRadius = 0.0;
                graph->pixelsToCoords(indeicator->start->pixelPosition(), startAngle, startRadius);

                double endAngle = 0.0;
                double endRadius = 0.0;
                graph->pixelsToCoords(indeicator->end->pixelPosition(), endAngle, endRadius);

                double difference = std::abs(startAngle - endAngle);
                this->item(i, 2)->setText(QString::number(difference));
            }
            else
            {
                if (tracer->GetName() == "最大值")
                {
                    tracer->setVisible(graph->visible());
                    if (!tracer->visible())
                    {
                        this->hideRow(i);
                        continue;
                    }
                    value = range.upper;
                    for (auto iter = graphData->begin(); iter != graphData->end(); ++iter)
                    {
                        if (qFuzzyCompare(iter->value, value))
                        {
                            key = iter->key;
                            break;
                        }
                    }
                }
                else if (tracer->GetName() == "最小值")
                {
                    tracer->setVisible(graph->visible());
                    if (!tracer->visible())
                    {
                        this->hideRow(i);
                        continue;
                    }
                    value = range.lower;
                    for (auto iter = graphData->begin(); iter != graphData->end(); ++iter)
                    {
                        if (qFuzzyCompare(iter->value, value))
                        {
                            key = iter->key;
                            break;
                        }
                    }
                }
                else if (tracer->GetName() == "平均值")
                {
                    int num = 0;
                    for (auto iter = graphData->begin(); iter != graphData->end(); ++iter)
                    {
                        ++num;
                        value += iter->value;
                    }
                    value /= num;
                }
                tracer->position->setCoords(key, value);
                this->item(i, 2)->setText(QString::number(value));
            }
            this->item(i, 0)->setText(graph->name());
            this->item(i, 1)->setText(tracer->GetName());
            this->showRow(i);

            if (graph->visible())
            {
                hasVisibleRow = true;
                this->showRow(i);
            }
            else
            {
                this->hideRow(i);
            }
        }
        hasVisibleRow ? this->show() : this->hide();
    }

    void PolarMeasureTableWidget::slot_updateTracerChange()
    {
        MeasureTableWidget::slot_updateTracerChange();
    }

} // namespace pst
